package com.linkoog.devtools.http.parser.spring;

import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethod;
import com.linkoog.devtools.http.common.HttpMethod;
import com.linkoog.devtools.http.parser.HttpServiceParser;
import com.linkoog.devtools.http.common.HttpParams;
import com.linkoog.devtools.http.parser.spring.common.SpringConstants;
import com.linkoog.devtools.http.parser.spring.handler.SpringHttpMethodHandler;
import com.linkoog.devtools.http.parser.spring.handler.SpringHttpParamHandler;
import com.linkoog.devtools.http.parser.spring.handler.SpringHttpUrlHandler;
import com.linkoog.devtools.http.raw_index.HttpServiceClassRawFileIndex;
import com.linkoog.devtools.http.raw_index.HttpServiceMethod;
import com.linkoog.devtools.metadata.raw_index.MethodMetadata;
import com.linkoog.devtools.metadata.raw_index.MethodMetadataRawFileIndex;
import com.linkoog.devtools.utils.PsiClassUtils;
import com.linkoog.devtools.utils.PsiMethodUtil;
import org.jetbrains.annotations.NotNull;

import java.util.List;

public class SpringHttpServiceParser implements HttpServiceParser {

    private final static String sourceType = "spring";

    private final SpringHttpUrlHandler springHttpUrlHandler = new SpringHttpUrlHandler();
    private final SpringHttpMethodHandler springHttpMethodHandler = new SpringHttpMethodHandler();
    private final SpringHttpParamHandler springHttpParamHandler = new SpringHttpParamHandler();

    public static SpringHttpServiceParser getInstance(){
        return EXTENSION_POINT_NAME.findExtension(SpringHttpServiceParser.class);
    }

    @Override
    public String getSourceType() {
        return sourceType;
    }

    @Override
    public boolean support(@NotNull PsiMethod psiMethod) {
        return PsiMethodUtil.parseMethodAnnotation(psiMethod, SpringConstants.METHOD_ANNOTATION_LIST, true) != null;
    }

    @Override
    public List<HttpMethod> parseHttpMethod(@NotNull PsiMethod psiMethod) {
        if (! support(psiMethod)) return null;

        return springHttpMethodHandler.parseHttpMethod(psiMethod);
    }

    @Override
    public HttpServiceMethod parse(@NotNull PsiMethod psiMethod) {
        if (! support(psiMethod)) return null;

        PsiClass psiClass = psiMethod.getContainingClass();
        if (psiClass == null || psiClass.getQualifiedName() == null) return null;

        //Module module =  ModuleUtil.findModuleForPsiElement(psiClass);


        MethodMetadata methodMetadata =  MethodMetadataRawFileIndex.getInstance(psiMethod.getProject()).getCache(psiMethod);
        if (methodMetadata == null) return null;

        List<HttpMethod> httpMethods = springHttpMethodHandler.parseHttpMethod(psiMethod);
        List<String> mappingUrls = springHttpUrlHandler.parseHttpUrl(psiMethod);
        HttpParams httpParams = springHttpParamHandler.parseHttpMethod(psiMethod, methodMetadata.getParamTypes());

        return new HttpServiceMethod(
                methodMetadata.getFilePath(),
                methodMetadata.getPsiElementOffset(),
                methodMetadata.getName(),
                methodMetadata.getParamTypes(),
                methodMetadata.getReturnType(),
                psiClass.getQualifiedName(),
                psiClass.getName(),
                getSourceType(),
                httpMethods,
                mappingUrls,
                httpParams.getHeaderParams(),
                httpParams.getPathParams(),
                httpParams.getQueryParams(),
                httpParams.getFileParams(),
                httpParams.getBodyParam()
        );
    }

}
